{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to pass callbacks in at runtime\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following concepts:\n",
    "\n",
    "- [Callbacks](/docs/concepts/#callbacks)\n",
    "\n",
    ":::\n",
    "\n",
    "In many cases, it is advantageous to pass in handlers instead when running the object. When we pass through [`CallbackHandlers`](https://api.js.langchain.com/interfaces/langchain_core_callbacks_base.CallbackHandlerMethods.html) using the `callbacks` keyword arg when executing an run, those callbacks will be issued by all nested objects involved in the execution. For example, when a handler is passed through to an Agent, it will be used for all callbacks related to the agent and all the objects involved in the agent's execution, in this case, the Tools and LLM.\n",
    "\n",
    "This prevents us from having to manually attach the handlers to each individual nested object. Here's an example using LangChain's built-in [`ConsoleCallbackHandler`](https://api.js.langchain.com/classes/langchain_core_tracers_console.ConsoleCallbackHandler.html):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[32m[chain/start]\u001b[39m [\u001b[90m\u001b[1m1:chain:RunnableSequence\u001b[22m\u001b[39m] Entering Chain run with input: {\n",
      "  \"number\": \"2\"\n",
      "}\n",
      "\u001b[32m[chain/start]\u001b[39m [\u001b[90m1:chain:RunnableSequence > \u001b[1m2:prompt:ChatPromptTemplate\u001b[22m\u001b[39m] Entering Chain run with input: {\n",
      "  \"number\": \"2\"\n",
      "}\n",
      "\u001b[36m[chain/end]\u001b[39m [\u001b[90m1:chain:RunnableSequence > \u001b[1m2:prompt:ChatPromptTemplate\u001b[22m\u001b[39m] [1ms] Exiting Chain run with output: {\n",
      "  \"lc\": 1,\n",
      "  \"type\": \"constructor\",\n",
      "  \"id\": [\n",
      "    \"langchain_core\",\n",
      "    \"prompt_values\",\n",
      "    \"ChatPromptValue\"\n",
      "  ],\n",
      "  \"kwargs\": {\n",
      "    \"messages\": [\n",
      "      {\n",
      "        \"lc\": 1,\n",
      "        \"type\": \"constructor\",\n",
      "        \"id\": [\n",
      "          \"langchain_core\",\n",
      "          \"messages\",\n",
      "          \"HumanMessage\"\n",
      "        ],\n",
      "        \"kwargs\": {\n",
      "          \"content\": \"What is 1 + 2?\",\n",
      "          \"additional_kwargs\": {},\n",
      "          \"response_metadata\": {}\n",
      "        }\n",
      "      }\n",
      "    ]\n",
      "  }\n",
      "}\n",
      "\u001b[32m[llm/start]\u001b[39m [\u001b[90m1:chain:RunnableSequence > \u001b[1m3:llm:ChatAnthropic\u001b[22m\u001b[39m] Entering LLM run with input: {\n",
      "  \"messages\": [\n",
      "    [\n",
      "      {\n",
      "        \"lc\": 1,\n",
      "        \"type\": \"constructor\",\n",
      "        \"id\": [\n",
      "          \"langchain_core\",\n",
      "          \"messages\",\n",
      "          \"HumanMessage\"\n",
      "        ],\n",
      "        \"kwargs\": {\n",
      "          \"content\": \"What is 1 + 2?\",\n",
      "          \"additional_kwargs\": {},\n",
      "          \"response_metadata\": {}\n",
      "        }\n",
      "      }\n",
      "    ]\n",
      "  ]\n",
      "}\n",
      "\u001b[36m[llm/end]\u001b[39m [\u001b[90m1:chain:RunnableSequence > \u001b[1m3:llm:ChatAnthropic\u001b[22m\u001b[39m] [766ms] Exiting LLM run with output: {\n",
      "  \"generations\": [\n",
      "    [\n",
      "      {\n",
      "        \"text\": \"1 + 2 = 3\",\n",
      "        \"message\": {\n",
      "          \"lc\": 1,\n",
      "          \"type\": \"constructor\",\n",
      "          \"id\": [\n",
      "            \"langchain_core\",\n",
      "            \"messages\",\n",
      "            \"AIMessage\"\n",
      "          ],\n",
      "          \"kwargs\": {\n",
      "            \"content\": \"1 + 2 = 3\",\n",
      "            \"tool_calls\": [],\n",
      "            \"invalid_tool_calls\": [],\n",
      "            \"additional_kwargs\": {\n",
      "              \"id\": \"msg_01SGGkFVbUbH4fK7JS7agerD\",\n",
      "              \"type\": \"message\",\n",
      "              \"role\": \"assistant\",\n",
      "              \"model\": \"claude-3-sonnet-20240229\",\n",
      "              \"stop_sequence\": null,\n",
      "              \"usage\": {\n",
      "                \"input_tokens\": 16,\n",
      "                \"output_tokens\": 13\n",
      "              },\n",
      "              \"stop_reason\": \"end_turn\"\n",
      "            },\n",
      "            \"response_metadata\": {\n",
      "              \"id\": \"msg_01SGGkFVbUbH4fK7JS7agerD\",\n",
      "              \"model\": \"claude-3-sonnet-20240229\",\n",
      "              \"stop_sequence\": null,\n",
      "              \"usage\": {\n",
      "                \"input_tokens\": 16,\n",
      "                \"output_tokens\": 13\n",
      "              },\n",
      "              \"stop_reason\": \"end_turn\"\n",
      "            }\n",
      "          }\n",
      "        }\n",
      "      }\n",
      "    ]\n",
      "  ],\n",
      "  \"llmOutput\": {\n",
      "    \"id\": \"msg_01SGGkFVbUbH4fK7JS7agerD\",\n",
      "    \"model\": \"claude-3-sonnet-20240229\",\n",
      "    \"stop_sequence\": null,\n",
      "    \"usage\": {\n",
      "      \"input_tokens\": 16,\n",
      "      \"output_tokens\": 13\n",
      "    },\n",
      "    \"stop_reason\": \"end_turn\"\n",
      "  }\n",
      "}\n",
      "\u001b[36m[chain/end]\u001b[39m [\u001b[90m\u001b[1m1:chain:RunnableSequence\u001b[22m\u001b[39m] [778ms] Exiting Chain run with output: {\n",
      "  \"lc\": 1,\n",
      "  \"type\": \"constructor\",\n",
      "  \"id\": [\n",
      "    \"langchain_core\",\n",
      "    \"messages\",\n",
      "    \"AIMessage\"\n",
      "  ],\n",
      "  \"kwargs\": {\n",
      "    \"content\": \"1 + 2 = 3\",\n",
      "    \"tool_calls\": [],\n",
      "    \"invalid_tool_calls\": [],\n",
      "    \"additional_kwargs\": {\n",
      "      \"id\": \"msg_01SGGkFVbUbH4fK7JS7agerD\",\n",
      "      \"type\": \"message\",\n",
      "      \"role\": \"assistant\",\n",
      "      \"model\": \"claude-3-sonnet-20240229\",\n",
      "      \"stop_sequence\": null,\n",
      "      \"usage\": {\n",
      "        \"input_tokens\": 16,\n",
      "        \"output_tokens\": 13\n",
      "      },\n",
      "      \"stop_reason\": \"end_turn\"\n",
      "    },\n",
      "    \"response_metadata\": {\n",
      "      \"id\": \"msg_01SGGkFVbUbH4fK7JS7agerD\",\n",
      "      \"model\": \"claude-3-sonnet-20240229\",\n",
      "      \"stop_sequence\": null,\n",
      "      \"usage\": {\n",
      "        \"input_tokens\": 16,\n",
      "        \"output_tokens\": 13\n",
      "      },\n",
      "      \"stop_reason\": \"end_turn\"\n",
      "    }\n",
      "  }\n",
      "}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m\"1 + 2 = 3\"\u001b[39m,\n",
       "    tool_calls: [],\n",
       "    invalid_tool_calls: [],\n",
       "    additional_kwargs: {\n",
       "      id: \u001b[32m\"msg_01SGGkFVbUbH4fK7JS7agerD\"\u001b[39m,\n",
       "      type: \u001b[32m\"message\"\u001b[39m,\n",
       "      role: \u001b[32m\"assistant\"\u001b[39m,\n",
       "      model: \u001b[32m\"claude-3-sonnet-20240229\"\u001b[39m,\n",
       "      stop_sequence: \u001b[1mnull\u001b[22m,\n",
       "      usage: { input_tokens: \u001b[33m16\u001b[39m, output_tokens: \u001b[33m13\u001b[39m },\n",
       "      stop_reason: \u001b[32m\"end_turn\"\u001b[39m\n",
       "    },\n",
       "    response_metadata: {}\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m\"1 + 2 = 3\"\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: {\n",
       "    id: \u001b[32m\"msg_01SGGkFVbUbH4fK7JS7agerD\"\u001b[39m,\n",
       "    type: \u001b[32m\"message\"\u001b[39m,\n",
       "    role: \u001b[32m\"assistant\"\u001b[39m,\n",
       "    model: \u001b[32m\"claude-3-sonnet-20240229\"\u001b[39m,\n",
       "    stop_sequence: \u001b[1mnull\u001b[22m,\n",
       "    usage: { input_tokens: \u001b[33m16\u001b[39m, output_tokens: \u001b[33m13\u001b[39m },\n",
       "    stop_reason: \u001b[32m\"end_turn\"\u001b[39m\n",
       "  },\n",
       "  response_metadata: {\n",
       "    id: \u001b[32m\"msg_01SGGkFVbUbH4fK7JS7agerD\"\u001b[39m,\n",
       "    model: \u001b[32m\"claude-3-sonnet-20240229\"\u001b[39m,\n",
       "    stop_sequence: \u001b[1mnull\u001b[22m,\n",
       "    usage: { input_tokens: \u001b[33m16\u001b[39m, output_tokens: \u001b[33m13\u001b[39m },\n",
       "    stop_reason: \u001b[32m\"end_turn\"\u001b[39m\n",
       "  },\n",
       "  tool_calls: [],\n",
       "  invalid_tool_calls: []\n",
       "}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { ConsoleCallbackHandler } from \"@langchain/core/tracers/console\";\n",
    "import { ChatPromptTemplate } from \"@langchain/core/prompts\";\n",
    "import { ChatAnthropic } from \"@langchain/anthropic\";\n",
    "\n",
    "const handler = new ConsoleCallbackHandler();\n",
    "\n",
    "const prompt = ChatPromptTemplate.fromTemplate(`What is 1 + {number}?`);\n",
    "const model = new ChatAnthropic({\n",
    "  model: \"claude-3-sonnet-20240229\",\n",
    "});\n",
    "\n",
    "const chain = prompt.pipe(model);\n",
    "\n",
    "await chain.invoke({ number: \"2\" }, { callbacks: [handler] });"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If there are already existing callbacks associated with a module, these will run in addition to any passed in at runtime.\n",
    "\n",
    "## Next steps\n",
    "\n",
    "You've now learned how to pass callbacks at runtime.\n",
    "\n",
    "Next, check out the other how-to guides in this section, such as how to create your own [custom callback handlers](/docs/how_to/custom_callbacks)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
